package com.bdult.vh.common;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;

import com.bdult.vh.service.CommonService;
import com.bdult.vh.service.OrderService;

public class CommonUtil {
	
	@Autowired
	private static CommonService commonService;
	
	@Autowired
	private static OrderService orderService;
	
	public static String getCreateGuest(HttpServletRequest request) {
		HttpSession session = request.getSession();
		String guest_id = (String)session.getAttribute("guest_id");
		if(guest_id==null) {
			Random rand = new Random(System.currentTimeMillis()); // seed 생성
			guest_id = "guest_" + Math.abs(rand.nextInt(9999)+1); 	//1-1000까지 숫자 
			System.out.println("CREATE GUEST ID = " + guest_id);
		}		
		session.setAttribute("guest_id", guest_id);
		
		return guest_id;
	}
	
	/**
	   * 문자열을 MD5로 인코딩
	   * since 2009. 4. 7.
	   * @param password 인코딩할 문자열
	   * @return MD5인코딩된 문자열
	   */
	  public static synchronized String convertPasswordMD5(String password) {
	    String newChar;
	    try{

	      if( ( password==null ) || ( password.length() == 0 ) ) {
	        newChar = "";
	      } else {
	        MessageDigest md = MessageDigest.getInstance("MD5");
	        md.update( password.getBytes() );

	        byte [] raw = md.digest();

	        newChar = byteToHex(raw);

	      }
	      
	    } catch (Exception e) {
	      return "";
	    }
	    return newChar;
	  }
	  
	  /**
	   * 파라메터가  NULL, 또는 빈값일 경우 공백문자("") 반환
	   * 이상없을 경우 원본문자열 반환
	   * since 2009. 4. 7.
	   * @param str 원본문자열
	   * @return String 공백문자열 또는,  원본문자열
	   */
	  public static synchronized String checkNullString (String str){
	    String strTmp;
	    try {
	      if (str!=null && str.length()>0 && !str.equals(""))
	        strTmp = str.trim();
	      else
	        strTmp = "";
	    } catch (Exception e) {
	        strTmp = "";
	    }
	    return strTmp.trim();
	  }
	  
	  /**
	   * byte코드를  hex코드로 변환
	   * since 2009. 4. 7.
	   * @param data hex코드로 변환할 byte코드 배열
	   * @return String hexcode 문자열
	   */
	  public static synchronized String byteToHex(byte[] data) {
	    StringBuffer buf = new StringBuffer();
	    for ( int i = 0; i < data.length;  i++) {
	      buf.append(byteToHex(data[i]).toUpperCase());
	    }
	    return buf.toString();
	  }
	  
	  /**
	   * byte코드를  hex코드로 변환
	   * since 2009. 4. 7.
	   * @param data hex코드로 변환할 byte코드
	   * @return hexcode 문자
	   */
	  private static synchronized String byteToHex(byte data) {
	    StringBuffer buf = new StringBuffer();
	    buf.append(toHexChar((data >>> 4) & 0x0F));
	    buf.append(toHexChar(data & 0x0F));
	    return buf.toString();
	  }
	  
	  /**
	   * byteToHex함수의 내부동작
	   * since 2009. 4. 7.
	   * @param i
	   * @return
	   */
	  private static synchronized char toHexChar(int i) {
	    if ((i >= 0) && (i <= 9)) {
	      return (char) ('0' + i);
	    } else {
	      return (char) ('a' + (i -10));
	    }
	  }
	  
	  /**
	   * 문자열을  enc 형식으로 인코딩
	   * since 2009. 4. 3.
	   * @param src 원본문자열
	   * @param enc 인코딩타입
	   * @return String
	   */
	  public static synchronized String encodeURL(String src, String enc){
	    if (src != null) {
	      try{
	        src = URLEncoder.encode(src, enc);
	      }catch(UnsupportedEncodingException e){
	        System.out.println(e.getMessage());
	      }
	    }
	    return src;
	  }
	  
	  
	  /*
	   * TBLPOINT 등록
	   * @param sOrdno 주문번호
	   * @param sCstmNo 회원번호
	   * @param sRoleNo 정책번호
	   * @param sAccumpt 포인트
	   * @param sRemark1 비고1
	   * @param sRemark2 비고2
	   * @param sUse 사용여부
	   * 20120125 김창환
	   */
	  //주문번호,회원번호,정책번호,적립차감구분,적립포인트,비고1(코멘트),비고2(적립차감이력),사용여부
	  public static void insertPoint(String sOrdno, String sCstmNo, String sRoleNo, String sInDeCl, String sAccumpt, String sRemark1, String sRemark2, String sUse, String adminid) throws Exception {
	    int idx = 1;
	    long iPOINTNO = 0L;
	    
	    try {
	      iPOINTNO = getMaxNumber("TBLPOINT.POINTNO", true);
		 	
	      HashMap<String,Object> paramMap = new HashMap<String,Object>();
	      paramMap.put("POINTNO", iPOINTNO);
	      paramMap.put("ORDNO", UtilBean.checkNullString(sOrdno));
	      paramMap.put("CSTMNO", UtilBean.checkNullString(sCstmNo));
	      paramMap.put("ROLENO", UtilBean.checkNullString(sRoleNo));
	      paramMap.put("INDECL", UtilBean.checkNullString(sInDeCl));
	      paramMap.put("ACCUMPT", UtilBean.checkNullString(sAccumpt));
	      paramMap.put("REMARK1", UtilBean.checkNullString(sRemark1));
	      paramMap.put("REMARK2", UtilBean.checkNullString(sRemark2));
	      paramMap.put("REGID", UtilBean.checkNullString(adminid));
	      paramMap.put("UPDID", UtilBean.checkNullString(adminid));
	      paramMap.put("USEFL", UtilBean.checkNullString(sUse));
	      commonService.insertPoint(paramMap);
	      
	    } finally {
	    }
	    
	  }
	  
	  
	//재고처리(구분,사유코드,상품코드,sap코드,전산재고,출고예정,안전재고,입고예정(x),불량재고(x),로스재고(x),변동수량,코멘트,판매수량,플래그)
	  /**
	   * 상품/사은품 - 변동재고이력 추가 공통으로 쓸것
	   * TBLSTOCK 등록
	   * 
	   * @since 20120216
	   * @author 김지연
	   * @param sTypeId 상품/사은품 구분 (x)
	   * @param sCode 재고변동사유코드
	   * @param sPrdCd 상품코드,사은품코드
	   * @param sSapCd SAP코드
	   * @param iGoodStk 전산재고
	   * @param iDlvrSrv 출고예정
	   * @param iSafeStk 안전재고
	   * @param iStrgrSrv 입고예정
	   * @param iBadStk 불량재고 (x)
	   * @param iLossStk 로스재고
	   * @param sChngQty 변동수량
	   * @param sChngComment 코멘트
	   * @param iCnt 상품(판매수량)/사은품(총출고수) - 주문에서 필요
	   * @param flag true-정상/false-롤백 주문에서 필요
	   * @throws Exception
	   */
	  //재고처리(구분,사유코드,상품코드,sap코드,전산재고,출고예정,안전재고,변동수량,코멘트,판매수량,플래그)
	  public static void insertStock(String sTypeId, String sCode, String sPrdCd, String sSapCd, long iGoodStk, long iDlvrSrv, long iSafeStk, String sChngQty, String sChngComment, long iCnt, boolean flag, String adminid) throws Exception {
	    int idx = 1;
	    long iStkNo = 0L;
	    String sGoodStkOp = "";
	    String sDlvrSrvOp = "";
	    String sSalQty = "";
	    String sOp = "";
	    HashMap<String,Object> htReturn = new HashMap<String,Object>();
	    String sSalStatCD = "";
	    String sTable = "";
	    String sPrcID = "";
	    String sTotalField = "";
	    
	    int nTotalGoodStk = 0;
	    int nTotalDlvrSrv = 0;
	    int nTotalSafeStk = 0;
	    
	    try {
	      /********************************************************************************************/
	      /** type(P:상품,R:사은품(x)) **/
	      /** 현재 재고 조회 **/
	      /********************************************************************************************/
	      if (UtilBean.checkNullString(sTypeId).equals("P")) {
	    	  HashMap<String,Object> paramMap = new HashMap<String,Object>();
		      paramMap.put("PRDCD", UtilBean.checkNullString(sPrdCd));
		      paramMap.put("SAPCD", UtilBean.checkNullString(sSapCd));
		      htReturn = orderService.getStock(paramMap);

		      nTotalGoodStk = UtilBean.convertToIntR(UtilBean.checkNullString(htReturn.get("GOODSTK")), 0);
		      nTotalDlvrSrv = UtilBean.convertToIntR(UtilBean.checkNullString(htReturn.get("DLVRSRV")), 0);
		      nTotalSafeStk = UtilBean.convertToIntR(UtilBean.checkNullString(htReturn.get("SAFESTK")), 0);
	      } 

	      
	      /********************************************************************************************/
	      /** 정상 재고 진행 또는 비정상 재고 롤백 **/
	      /********************************************************************************************/
//	    주문접수(출고예정+,재고-)(SR01)      
//	    배송중(출고예정-)(SR02)
//	    배송완료(엑셀업로드)(판매수량+)(SR03)
//	    취소완료(출고예정-,재고+)(SR04)      
//	    반품회수완료(정상)(재고+,판매수량-)(SR05)
	      if (flag) {
	        // 재고
	        if (sCode.equals("SR04") || sCode.equals("SR05")) {
	          sGoodStkOp = "p";
	        }else if (sCode.equals("SR01")) {
	          sGoodStkOp = "m";
	        }
	        // 출고예정
	        if (sCode.equals("SR01")) {
	          sDlvrSrvOp = "p";
	        }else if (sCode.equals("SR02") || sCode.equals("SR04")) {
	          sDlvrSrvOp = "m";
	        }
	        // 판매수량
	        if (sCode.equals("SR03")) {
	          sSalQty = "p";
	        }else if (sCode.equals("SR05")) {
	          sSalQty = "m";
	        }
	      } else {
	        sOp = "-";
	        // 재고
	        if (sCode.equals("SR04") || sCode.equals("SR05")) {
	          sGoodStkOp = "m";
	        }else if (sCode.equals("SR01")) {
	          sGoodStkOp = "p";
	        }
	        // 출고예정
	        if (sCode.equals("SR01")) {
	          sDlvrSrvOp = "m";
	        }else if (sCode.equals("SR02") || sCode.equals("SR04")) {
	          sDlvrSrvOp = "p";
	        }
	        // 판매수량
	        if (sCode.equals("SR03")) {
	          sSalQty = "m";
	        }else if (sCode.equals("SR05")) {
	          sSalQty = "p";
	        }
	      }

    	  HashMap<String,Object> paramMap = new HashMap<String,Object>();
    	  
	      /********************************************************************************************/
	      /** 재고 이력 저장(TBLSTOCK) **/
	      /********************************************************************************************/
	      if (sTypeId.equals("P")) {
    	  paramMap.put("CLCD", UtilBean.checkNullString("1"));
	      }
	      paramMap.put("PRDCD", UtilBean.checkNullString(sPrdCd));
	      paramMap.put("SAPCD", UtilBean.checkNullString(sSapCd));
	      //paramMap.put("STKNO", iStkNo);
	      if (sCode.equals("SR04") || sCode.equals("SR05")) {
	      paramMap.put("GOODSTK", nTotalGoodStk + UtilBean.convertToLong(sOp + sChngQty));
	      } else if (sCode.equals("SR01")) {
	      paramMap.put("GOODSTK", nTotalGoodStk - UtilBean.convertToLong(sOp + sChngQty));
	      } else {
	      paramMap.put("GOODSTK", nTotalGoodStk);
	      }
	      if (sCode.equals("SR01")) {
	      paramMap.put("DLVRSRV", UtilBean.convertToLong(sOp + sChngQty));
	      } else if (sCode.equals("SR02") || sCode.equals("SR04")) {
	      paramMap.put("DLVRSRV", UtilBean.convertToLong(sOp + sChngQty));
	      } else {
		  paramMap.put("DLVRSRV", "0");
	      }
	      paramMap.put("SAFESTK", iSafeStk);
	      paramMap.put("STKRSNCD", sCode);
	      paramMap.put("CHNGQTY", sChngQty);
	      paramMap.put("CHNGCOMMENT", UtilBean.checkNullString(sChngComment));
	      paramMap.put("REGID", UtilBean.checkNullString(adminid));
	      int result = orderService.insertStock(paramMap);

	      /********************************************************************************************/
	      /** 재고수량 업데이트 **/
	      /********************************************************************************************/
//	    주문접수(출고예정+,재고-)(SR08) [비활성]      1      
//	    배송중(출고예정-,전산재고-)(SR14) [비활성]  2   (전산재고 삭제)
//	    배송완료(엑셀업로드)(판매수량+)(SR17) [비활성]   3
//	    취소완료(출고예정-,재고+)(SR11) [비활성]  4      
//	    반품회수완료(정상)(입고예정-,재고+,전산재고+,판매수량-)(SR24) [비활성]  5 (입고예정, 전산재고 삭제)
//	      GOODSTK(재고),SALQTY(판매수량),DLVRSRV(출고예정),SAFESTK(안전재고)
	      
	      if (sCode.equals("SR01")) {
	    	HashMap<String,Object> paramMaps = new HashMap<String,Object>();
	    	paramMaps.put("sDlvrSrvOp", UtilBean.checkNullString(sDlvrSrvOp));
	    	paramMaps.put("sChngQty", UtilBean.convertToLong(sChngQty));
	    	paramMaps.put("sGoodStkOp", UtilBean.checkNullString(sGoodStkOp));
	    	paramMaps.put("sChngQty", UtilBean.convertToLong(sChngQty));
	    	paramMaps.put("UPDID", UtilBean.checkNullString(adminid));
	    	paramMaps.put("PRDCD", UtilBean.checkNullString(sPrdCd));
	    	paramMaps.put("SAPCD", UtilBean.checkNullString(sSapCd));
		    orderService.updateDlvrsrvSR01(paramMaps);
	      } else if (sCode.equals("SR02")) {
	        HashMap<String,Object> paramMaps = new HashMap<String,Object>();
	    	paramMaps.put("sDlvrSrvOp", UtilBean.checkNullString(sDlvrSrvOp));
	    	paramMaps.put("sChngQty", UtilBean.convertToLong(sChngQty));
	    	paramMaps.put("UPDID", UtilBean.checkNullString(adminid));
	    	paramMaps.put("PRDCD", UtilBean.checkNullString(sPrdCd));
	    	paramMaps.put("SAPCD", UtilBean.checkNullString(sSapCd));
		    orderService.updateDlvrsrvSR02(paramMaps);
	      } else if (sCode.equals("SR03")) {
		    HashMap<String,Object> paramMaps = new HashMap<String,Object>();
		    paramMaps.put("sSalQty", UtilBean.checkNullString(sDlvrSrvOp));
		    paramMaps.put("sChngQty", UtilBean.convertToLong(sChngQty));
		    paramMaps.put("UPDID", UtilBean.checkNullString(adminid));
		    paramMaps.put("PRDCD", UtilBean.checkNullString(sPrdCd));
		    paramMaps.put("SAPCD", UtilBean.checkNullString(sSapCd));
			orderService.updateDlvrsrvSR03(paramMaps);
	      } else if (sCode.equals("SR04")) {
	    	HashMap<String,Object> paramMaps = new HashMap<String,Object>();
		    paramMaps.put("sDlvrSrvOp", UtilBean.checkNullString(sDlvrSrvOp));
		    paramMaps.put("sChngQty", UtilBean.convertToLong(sChngQty));
		    paramMaps.put("sGoodStkOp", UtilBean.checkNullString(sGoodStkOp));
		    paramMaps.put("sChngQty", UtilBean.convertToLong(sChngQty));
		    paramMaps.put("UPDID", UtilBean.checkNullString(adminid));
		    paramMaps.put("PRDCD", UtilBean.checkNullString(sPrdCd));
		    paramMaps.put("SAPCD", UtilBean.checkNullString(sSapCd));
			orderService.updateDlvrsrvSR04(paramMaps);
	      } else if (sCode.equals("SR05")) {
	    	HashMap<String,Object> paramMaps = new HashMap<String,Object>();
		    paramMaps.put("sGoodStkOp", UtilBean.checkNullString(sGoodStkOp));
		    paramMaps.put("sChngQty", UtilBean.convertToLong(sChngQty));
		    paramMaps.put("UPDID", UtilBean.checkNullString(adminid));
		    paramMaps.put("PRDCD", UtilBean.checkNullString(sPrdCd));
		    paramMaps.put("SAPCD", UtilBean.checkNullString(sSapCd));
			orderService.updateDlvrsrvSR05(paramMaps);
	      }
	//System.out.println("insertStock query = " + query);
	      /********************************************************************************************/
	      /** 판매중,일시품절 상태 변경 **/
	      /********************************************************************************************/
	      int nResult = 0;
	      if(!sGoodStkOp.equals("")){ //재고변동이 있을시에 상품 판매상태 변경
	        if (sGoodStkOp.equals("+")) {
	          //재고
	          nResult = UtilBean.convertToInt(nTotalGoodStk + UtilBean.convertToLong(sChngQty));
	        } else {
	          nResult = UtilBean.convertToInt(nTotalGoodStk - UtilBean.convertToLong(sChngQty));
	        }
	        
	        if (nResult <= 0) {
	          sSalStatCD = "PS02";
	        } else {
	          sSalStatCD = "PS01";
	        }
	        /********************************************************************************************/
	        /** 판매상태(SAP기준) 업데이트 **/
	        /********************************************************************************************/
	        HashMap<String,Object> paramMaps = new HashMap<String,Object>();
		    paramMaps.put("SALSTATCD", UtilBean.checkNullString(sSalStatCD));
		    paramMaps.put("PRDCD", UtilBean.checkNullString(sPrdCd));
		    paramMaps.put("SAPCD", UtilBean.checkNullString(sSapCd));
			result = orderService.updateSaleState(paramMaps);
			
	        /********************************************************************************************/
	        /** TBLPRODUCTOPTION 판매중 상태 조회 **/
	        /********************************************************************************************/
			HashMap<String,Object> htData = new HashMap<String,Object>();
			htData = orderService.getOnSaleState(UtilBean.checkNullString(sPrdCd));
	        
	        /********************************************************************************************/
	        /** TBLPRODUCT 판매상태 조회 **/
	        /********************************************************************************************/
			HashMap<String,Object> htData2 = new HashMap<String,Object>();
			htData2 = orderService.getSaleState(UtilBean.checkNullString(sPrdCd));
	        
	        /********************************************************************************************/
	        /** TBLPRODUCT 판매상태 업데이트 **/
	        /********************************************************************************************/
	        if (htData2 != null) {
	          String sAutoSalStatcd = "";
	          String sChkStat = UtilBean.checkNullString(htData2.get("SALSTATCD"));
	          //일시중지(관리자가 직접), 판매중단(승인해야 바꿀수 있음.관리자가 직접)
	          if (!sChkStat.equals("PS03") && !sChkStat.equals("PS04")) {
	            
	            if (htData != null) {
	              if (UtilBean.checkNullString(htData.get("PRDCD")).equals("")) {
	                sAutoSalStatcd = "PS02";
	              } else {
	                sAutoSalStatcd = "PS01";
	              }
	            } else {
	              sAutoSalStatcd = "PS01";
	            }
	            
	            HashMap<String,Object> paramMapPdt = new HashMap<String,Object>();
	            paramMapPdt.put("SALSTATCD", UtilBean.checkNullString(sAutoSalStatcd));
	            paramMapPdt.put("PRDCD", UtilBean.checkNullString(sPrdCd));
				result = orderService.updateSaleStatePdt(paramMaps);

	          }
	        }
	      }
	    } finally {
	     
	    }
	  }
	  
	  /**
	   * tblSequence의 keyID와 일치하는 keyNo의 최대값 +1 반환
	   * 
	   * @param sKeyID : tblSequence의 keyID
	   * @return long
	   * @Author 황세원
	   */
	  private static long getMaxNumber(String sKeyID, boolean flag) throws Exception {
		  long iKeyNo = -1;
	    
	      if (flag) {
	    	  
	    	  int iAffected = 0;
	    	  iAffected = commonService.updateSequence(sKeyID);
	    	  if (iAffected <= 0) {
	    		  commonService.insertSequence(sKeyID);
	    	  }
	      }
	      
	      iKeyNo = commonService.selectSequence(sKeyID);;
	      
	      return iKeyNo;
	  }
}
